#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <iostream>
#include "mosquitto.h"
#include "cJSON.h"
#include "mqtt_pub.h"

#define HOST "localhost"
#define PORT 1883
#define KEEP_ALIVE 60
#define MSG_MAX_SIZE 512

static int running = 1;

MqttPub::MqttPub()
{
        initMqtt();
}
MqttPub::~MqttPub()
{
        mosquitto_destroy(mosq_);
        mosquitto_lib_cleanup();
        printf("End!\n");
}
void MqttPub::run()
{
        // mosquitto_loop_start作用是开启一个线程，在线程里不停的调用 mosquitto_loop() 来处理网络信息
        int loop = mosquitto_loop_start(mosq_);
        if (loop != MOSQ_ERR_SUCCESS)
        {
                std::cout << "服务端loop错误" << std::endl;
                return;
        }
        char *message = genJsonData();
        while (true)
        {
                /*发布消息*/
                mosquitto_publish(mosq_, NULL, "machine_info_analyze", strlen(message) + 1, message, 0, 0);
                usleep(100000);
        }
}

void MqttPub::initMqtt()
{
        // 初始化libmosquitto库
        mosquitto_lib_init();
        // 创建一个发布端实例
        mosq_ = mosquitto_new("pub_mqtt", true, NULL);
        if (mosq_ == NULL)
        {
                std::cout << "创建mqtt客户端失败" << std::endl;
                mosquitto_lib_cleanup();
                return;
        }

        // 设置回调函数
        mosquitto_connect_callback_set(mosq_, MqttPub::onConnectCallback);
         mosquitto_disconnect_callback_set(mosq_, MqttPub::onDisconnectCallback);
         mosquitto_publish_callback_set(mosq_, MqttPub::onPublishCallback);

        // 连接服务器
        // 参数：句柄、ip（host）、端口、心跳
        if (mosquitto_connect(mosq_, HOST, PORT, KEEP_ALIVE))
        {
                std::cout << "连接服务器失败" << std::endl;
                mosquitto_destroy(mosq_);
                mosquitto_lib_cleanup();
                return;
        }
}

void MqttPub::onConnectCallback(struct mosquitto *mosq, void *obj, int rc)
{
        std::cout << "已与客户端建立连接" << std::endl;
}
void MqttPub::onDisconnectCallback(struct mosquitto *mosq, void *obj, int rc)
{
        std::cout << "断开与客户端的连接" << std::endl;
        running = 0;
}
void MqttPub::onPublishCallback(struct mosquitto *mosq, void *obj, int mid)
{
        std::cout << "进入话题发布回调" << std::endl;
}

cJSON *MqttPub::createPointArray(double x, double y, double z)
{
        cJSON *array = cJSON_CreateArray();
        cJSON_AddItemToArray(array, cJSON_CreateNumber(x));
        cJSON_AddItemToArray(array, cJSON_CreateNumber(y));
        cJSON_AddItemToArray(array, cJSON_CreateNumber(z));
        return array;
}
cJSON *MqttPub::createQualShapeArray(cJSON *p1, cJSON *p2, cJSON *p3, cJSON *p4)
{
        cJSON *obj_array = cJSON_CreateArray();
        cJSON_AddItemToObject(obj_array, "car_top_p", p1);
        cJSON_AddItemToObject(obj_array, "car_top_p", p2);
        cJSON_AddItemToObject(obj_array, "car_top_p", p3);
        cJSON_AddItemToObject(obj_array, "car_top_p", p4);
        return obj_array;
}
char *MqttPub::genJsonData()
{
        cJSON *car_top_p = createPointArray(0.11100000143051147, 1.1109999418258667, 2.1110000610351562);
        cJSON *cabin_top_p_p1 = createPointArray(0.22200000286102295,
                                                 1.222000002861023,
                                                 2.2219998836517334);
        cJSON *cabin_top_p_p2 = createPointArray(10.222000122070312,
                                                 11.222000122070312,
                                                 12.222000122070312);
        cJSON *cabin_top_p_p3 = createPointArray(20.222000122070312,
                                                 21.222000122070312,
                                                 22.222000122070312);
        cJSON *cabin_top_p_p4 = createPointArray(30.222000122070312,
                                                 31.222000122070312,
                                                 32.22200012207031);
        cJSON *cabin_top_p = createQualShapeArray(cabin_top_p_p1, cabin_top_p_p2, cabin_top_p_p3, cabin_top_p_p4);
        cJSON *root = cJSON_CreateObject();
        cJSON_AddItemToObject(root, "car_top_p", car_top_p);
        cJSON_AddItemToObject(root, "cabin_top_p", cabin_top_p);
        char *buff = cJSON_Print(root);
        // printf("\n%s\n", buff);
        return buff;
}
